package P132_BasicMethodsToAdvanceJavaPerformance;

import org.junit.Test;

/**
 * Desc:&emsp;&ensp;提升java性能的基础方法
 * 我们知道运行一段程序需要三种资源： CPU 、内存、1/0 ， 提升CPU 的处理速度可以加
 * 快代码的执行速度， 直接表现就是返回时间缩短了， 效率提高了； 内存是Java 程序必须考虑
 * 的问题， 在32 位的机器上， 一个JVM 最多只能使用2GB 的内存， 而且程序占用的内存越
 * 大， 寻址效率也就越低， 这也是影响效率的一个因素。1/0 是程序展示和存储数据的主要通
 * 道， 如果它很缓慢就会影响正常的显示效果。所以我们在编码时需要从这三个方面人手接口
 *
 * @author 李渊&emsp;liyuan7@yusys.com.cn
 * @version 1.0
 * @since V4.3&emsp;2022/5/20
 */
public class BasicMethodsToAdvanceJavaPerformance {
    //1.不要再循环条件中使用计算
    @Test
    public void test1() {
        int i = 0;
        final int count = 10;
        while (i < count * 2) {
            // Do something
        }
        // 应该替换为
        int total = count * 2;
        while (i < total) {
            // Do something
        }
    }

    //2.尽可能把变量声明为final static类型
    public String toChineseNum1(int num) {
        // 每次调用重新生成
        String[] cns = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
        return cns[num];
    }
    final  static String[] cns = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
    public String toChineseNum2(int num) {
        return cns[num];
    }

    /* 3.缩小变量作用范围
    关于变量， 能定义在方法内的就定义在方法内， 能定义在一个循环体内的就定义在循环
    体内， 能放置在一个try••••••catch 块内的就放置在该块内， 其目的是加快GC 的回收。*/


    /**
     * 4.频繁字符串操作应该使用StringBuilder或者StringBuffer{@link P054_String_StringBuffer_StringBuilder.String_StringBuffer_StringBuilder}
     */

    /**
     * 5.使用非线性检索
     * 如果在ArrayList 中存储了大量的数据， 使用indexOf 查找元素会比java.utils. Collections
     * binarysearch 的效率低很多， 原因是binarysearch 是二分搜索法， 而indexOf 使用的是逐个
     * 元素比对的方法。这里要注意： 使用binarysearch 搜索时， 元素必须进行排序， 否则准确不可靠
     * {@link P074_NoUseBinarySearch.NoUseBinarySearch}
     */


    /**
     * 6.覆写Exception 的fillInStackTrace 方法
     * fi111nStackTrace 方法是用来记录异常时的栈信息的， 这是非常耗时
     * 的动作， 如果我们在开发时不需要关注栈信息， 则可以覆盖之， 如下覆盖fi111nStackTrace 的
     * 自定义异常会使性能提升10 倍以上：
     */
    class MyException extends Exception{
        public MyException(String message, Throwable cause) {
            super(message, cause);
        }

        @Override
        public synchronized Throwable fillInStackTrace() {
            return this;
        }
    }

    /**
     * 7.不要建立冗余对象
     * @throws MyException
     */
    public void test7() throws MyException {
        String exceptionMsg = "出现了异常！";
        try{
            Thread.sleep(10);
        } catch (Exception e){
            throw new MyException(exceptionMsg,e);
        }
    }
}
